#include "ST75320.H"

#include "stm32f1xx_hal.h"

extern const unsigned char gImage_320240_1[9600];
extern const unsigned char gImage_320240_2[9600];
extern const unsigned char gImage_320240_3[9600];
extern const unsigned char gImage_frame_triangle[9600] ;

extern SPI_HandleTypeDef hspi1;

#define SPI_TIMEOUT 10
void write_com(uint8_t byte) {
	//HAL_GPIO_WritePin(LCM_A0_GPIO_Port, LCM_A0_Pin, GPIO_PIN_RESET);
	LCM_A0_GPIO_Port->BRR = (uint32_t)LCM_A0_Pin;
    HAL_SPI_Transmit(&hspi1, &byte, 1, SPI_TIMEOUT );
	//HAL_SPI_Transmit_IT(&hspi1, &byte, 1 );
}

void write_data(uint8_t byte) {
	//HAL_GPIO_WritePin(LCM_A0_GPIO_Port, LCM_A0_Pin, GPIO_PIN_SET);
	LCM_A0_GPIO_Port->BSRR = (uint32_t)LCM_A0_Pin;
    HAL_SPI_Transmit(&hspi1, &byte, 1, SPI_TIMEOUT );
}

void delay_ms(uint8_t time) {
	HAL_Delay(time);
}

/*
unsigned char i;
void write_com(unsigned char byte)
{
	//cs = 0;
	

	sck = 0;
	sda = 0;
	
	_nop_();
	sck = 1;
	
	for(i=0;i<8;i++)
	{
		sck=0;
		//_nop_();
		//_nop_();
		sda=(bit)(byte&0x80);
		byte <<= 1;
		sck=1;
		//_nop_();
		//_nop_();
	}
	cs = 1;
}

//serial 4-SPIд���ݣ�
void write_data(unsigned char byte)
{
	cs = 0;
	
	sck = 0;
	sda = 1;
	
	_nop_();
	sck = 1;
	
	for(i=0;i<8;i++)
	{
		sck=0;
		//_nop_();
		//_nop_();
		sda=(bit)(byte&0x80);
		sck=1;
		byte <<= 1;
		//_nop_();
		//_nop_();
	}
	
	cs = 1;
}

*/


void lcm_init(void) {


    HAL_GPIO_WritePin(LCM_RST_GPIO_Port, LCM_RST_Pin, GPIO_PIN_SET);
    HAL_Delay(10);
    HAL_GPIO_WritePin(LCM_RST_GPIO_Port, LCM_RST_Pin, GPIO_PIN_RESET);
    HAL_Delay(10);
    HAL_GPIO_WritePin(LCM_RST_GPIO_Port, LCM_RST_Pin, GPIO_PIN_SET);


    write_com(0xff);     //auto read disable
	write_com(0x96);
	write_data(0x30); 
	write_com(0x94);     //Download from OTP
delay_ms(50);   
				 
	write_com(0xFE);    //CMD MODE
	write_com(0xB0);    //Display Setting 
	write_data(0x03);     
	write_com(0xB3);  //Display Setting 
	write_data(0x04); 
		  
			  
	write_com(0xFC);    //CMD MODE
	write_com(0xAB);    //OSC ON
	write_com(0x69);    //Temperature Detection ON
	write_com(0x4E);    //TC Setting
	write_data(0x00);       // 0mv/'C should be adjusted by user
	write_data(0x00);       // 0mv/'C should be adjusted by user
	write_data(0x00);       // 0mv/'C should be adjusted by user 
	write_data(0x00);       // 0mv/'C should be adjusted by user 
	write_data(0x00);       // 0mv/'C should be adjusted by user 
	write_data(0x00);       // 0mv/'C should be adjusted by user 
	write_data(0x00);       // 0mv/'C should be adjusted by user 
	write_data(0x00);       // 0mv/'C should be adjusted by user 
	write_com(0x39);    //TC Flag
	write_data(0x00);       // 
	write_data(0x00);       //
	write_com(0x2b);    //Double FR
	write_data(0x00);       //x1
	write_com(0x66);    //Mono
	write_data(0x00);       //
	write_com(0x5f);    //Set Frame Rate
	write_data(0x33);       //80Hz
	write_data(0x33);       //

	write_com(0xEC);    //FR Compensation Temp. Range
	write_data(0x14);       // -20'c 
	write_data(0x41);       //  25'c
	write_data(0x6e);       // 70'c
	write_com(0xC4);    //COM Output Status
	write_data(0x02);       // 
	write_com(0xA1);    //MX
	write_com(0xA8);    //Sleep-Out                                                                                            
	write_com(0xA2);    //1/16bias  
	write_data(0x07);      
	
	write_com(0x25);
	write_data(0x20);
delay_ms(10);
	write_com(0x25);
	write_data(0x60);
delay_ms(10);
	write_com(0x25);
	write_data(0x72);
delay_ms(10);
	write_com(0x25);
	write_data(0x76);
//delay_ms(0x100); 
	delay_ms(0x50);
	delay_ms(0x50);	
	
	write_com(0x25);
	write_data(0x6f);
//delay_ms(0x500);
	delay_ms(0x50);
	delay_ms(0x50);	
	delay_ms(0x50);
	delay_ms(0x50);	
	delay_ms(0x50);
	
	write_com(0x25);
	write_data(0x7f);
//delay_ms(0x100);   
	delay_ms(0x50);
	delay_ms(0x50);
	
	
	write_com(0x81);    //Vop=24.4V                  
	//write_data(0x68);
	//write_data(0x01);  
	write_data(0x13);
	write_data(0x01);
	write_com(0xAF);    //Display ON

}

void display_setting(void) {
	write_com(0xc4);			//COM Output Status
	write_data(0x02);
	
	write_com(0x8a);			//Display Start Line
	write_data(0);
	
	write_com(0x84);			//Display Data Input/Output Direction
	
	write_com(0xa1);			//Column Address Direction
	
	write_com(0x6d);			//Display Area
	write_data(0x07);
	write_data(0x00);
}

void chess(void) {
	unsigned long c, p = 0;
	write_com(0xb1);			//Page Address
	write_data(0x00);
	
	write_com(0x13);			//Column Address
	write_data(0x00);
	write_data(0x00);
	
	write_com(0x1d);			//Display Data Write
	for(p = 0; p < 240/8; p++) {
		for(c = 0; c < 320/2; c++) {
			write_data(0x55);
			write_data(0xaa);
		}
	}
	
}

void drawImage(unsigned char * image) {
	unsigned long c, p = 0;
	write_com(0xb1);			//Page Address
	write_data(0x00);
	
	write_com(0x13);			//Column Address
	write_data(0x00);
	write_data(0x00);
	
	write_com(0x1d);			//Display Data Write
	
	/*for(p = 0; p < 240/8; p++) {
		for(c = 0; c < 320; c++) {
			write_data(*image++);
		}
	}*/
	LCM_A0_GPIO_Port->BSRR = (uint32_t)LCM_A0_Pin;
	HAL_SPI_Transmit(&hspi1, image, 320*240/8, 1000);
	
}

void lcm_test(void) {
    display_setting();

    while(1) {
        chess();
        HAL_Delay(1000);
		
		drawImage((unsigned char *)gImage_frame_triangle);
		HAL_Delay(1000);
		
		drawImage((unsigned char *)gImage_320240_1);
		HAL_Delay(1000);
		
		drawImage((unsigned char *)gImage_320240_2);
		HAL_Delay(1000);
		
		drawImage((unsigned char *)gImage_320240_3);
		HAL_Delay(1000);

    }
	
	
    // FULL

    // H LINE

    // V LINE

    // IMG
}
